package com.piece.blog.service;

import com.piece.blog.dto.TrainingQuestionDTO;
import com.piece.blog.dto.TrainingQuestionOptionDTO;
import com.piece.blog.model.TrainingQuestion;
import com.piece.blog.model.TrainingQuestionItem;
import com.piece.blog.repository.TrainingQuestionItemRepository;
import com.piece.blog.repository.TrainingQuestionRepository;
import com.piece.core.framework.enums.StatusType;
import com.piece.core.framework.enums.sql.SqlKey;
import com.piece.core.framework.support.bootstrap.Order;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.object.BeanUtil;
import com.piece.core.jpa.repository.BaseService;
import com.piece.core.log.config.UserContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;

@Service
@Transactional
public class TrainingQuestionService extends BaseService<TrainingQuestion, String> {

    @Autowired
    private TrainingQuestionRepository trainingQuestionRepository;

    @Autowired
    private TrainingQuestionItemRepository trainingQuestionItemRepository;

    @PostConstruct
    public void initRepository() {
        setRepository(trainingQuestionRepository);
    }

    public TrainingQuestionDTO loadByQuestionId(Long questionId, boolean reSort) {
        TrainingQuestionDTO question = new TrainingQuestionDTO();
        if (null != questionId) {
            TrainingQuestion trainingQuestion = findById(questionId);
            BeanUtil.copyProperties(trainingQuestion, question, true);
            // 填空题不乱序
            if ("3".equals(trainingQuestion.getType())) {
                reSort = false;
            }
            List<TrainingQuestionItem> items = findQuestionItems(question.getQuestionId(), reSort);
            List<TrainingQuestionOptionDTO> options = new ArrayList<>();
            items.stream().forEach(item -> {
                TrainingQuestionOptionDTO option = new TrainingQuestionOptionDTO();
                option.setType(item.getType());
                option.setLabel(item.getLabel());
                option.setValue(item.getValue());
                if (null != question.getOptionType() && !"0".equals(question.getOptionType())) {
                    option.setLabel(item.getValue());
                    option.setSrc(item.getLabel());
                }
                if ("3".equals(question.getType())) {
                    option.setValue(null);
                }
                options.add(option);
            });
            question.setOptions(options);
        } else {
            question.setType("0");
            question.setOptions(Collections.emptyList());
        }

        return question;
    }

    public boolean insertOrUpdate(TrainingQuestionDTO question) throws Exception {
        TrainingQuestion trainingQuestion;
        Long questionId = question.getQuestionId();
        if (null != questionId) {
            trainingQuestion = findById(questionId);
        } else {
            trainingQuestion = new TrainingQuestion();
            trainingQuestion.setStatus(StatusType.NORMAL.getCode());
            trainingQuestion.setCreateBy(Convert.toLong(UserContextHolder.getUserId(), null));
            trainingQuestion.setCreateTime(new Date());
        }

        BeanUtil.copyProperties(question, trainingQuestion, "status", "createBy", "createTime");
        insertOrUpdate(trainingQuestion);

        trainingQuestionItemRepository.deleteByProperties("questionId", questionId);

        List<TrainingQuestionItem> items = new ArrayList<>();
        List<TrainingQuestionOptionDTO> options = question.getOptions();
        for (TrainingQuestionOptionDTO option: options) {
            TrainingQuestionItem item = new TrainingQuestionItem();
            item.setQuestionId(trainingQuestion.getQuestionId());
            BeanUtil.copyProperties(option, item, true);
            item.setCreateBy(Convert.toLong(UserContextHolder.getUserId(), null));
            item.setCreateTime(new Date());
            items.add(item);
        }

        trainingQuestionItemRepository.batchInsert(items);
        return true;
    }

    public List<TrainingQuestionItem> findQuestionItems(Long questionId, boolean reSort) {
        List<TrainingQuestionItem> options = trainingQuestionItemRepository.findByCondition("questionId", questionId,
                Arrays.asList(new Order("itemId", SqlKey.ASC)));
        if (reSort) {
            Collections.shuffle(options);
        }

        return options;
    }
}
